/**
 * Copyright (c) 2017+ LocalStack contributors
 * Copyright (c) 2016 Atlassian Pty Ltd

 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at

 *     http://www.apache.org/licenses/LICENSE-2.0

 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Amazon States Lanaguage (ASL) Grammar for ANTLR v4
 *
 * Based on:
 * http://github.com/localstack/localstack
 * and
 * https://states-language.net/spec.html
 */

// $antlr-format alignTrailingComments true, columnLimit 150, maxEmptyLinesToKeep 1, reflowComments false, useTab false
// $antlr-format allowShortRulesOnASingleLine true, allowShortBlocksOnASingleLine true, minEmptyLines 0, alignSemicolons ownLine
// $antlr-format alignColons trailing, singleLineOverrulesHangingColon true, alignLexerCommands true, alignLabels true, alignTrailers true

lexer grammar ASLLexer;

// Symbols.
COMMA  : ',';
COLON  : ':';
LBRACK : '[';
RBRACK : ']';
LBRACE : '{';
RBRACE : '}';

// Literals.
TRUE  : 'true';
FALSE : 'false';
NULL  : 'null';

// Keywords.
COMMENT : '"Comment"';
STATES  : '"States"';
STARTAT : '"StartAt"';
VERSION : '"Version"';

TYPE     : '"Type"';
TASK     : '"Task"';
CHOICE   : '"Choice"';
FAIL     : '"Fail"';
SUCCEED  : '"Succeed"';
PASS     : '"Pass"';
WAIT     : '"Wait"';
PARALLEL : '"Parallel"';
MAP      : '"Map"';

CHOICES  : '"Choices"';
VARIABLE : '"Variable"';
DEFAULT  : '"Default"';
BRANCHES : '"Branches"';

AND                            : '"And"';
BOOLEANEQUALS                  : '"BooleanEquals"';
BOOLEANQUALSPATH               : '"BooleanEqualsPath"';
ISBOOLEAN                      : '"IsBoolean"';
ISNULL                         : '"IsNull"';
ISNUMERIC                      : '"IsNumeric"';
ISPRESENT                      : '"IsPresent"';
ISSTRING                       : '"IsString"';
ISTIMESTAMP                    : '"IsTimestamp"';
NOT                            : '"Not"';
NUMERICEQUALS                  : '"NumericEquals"';
NUMERICEQUALSPATH              : '"NumericEqualsPath"';
NUMERICGREATERTHAN             : '"NumericGreaterThan"';
NUMERICGREATERTHANPATH         : '"NumericGreaterThanPath"';
NUMERICGREATERTHANEQUALS       : '"NumericGreaterThanEquals"';
NUMERICGREATERTHANEQUALSPATH   : '"NumericGreaterThanEqualsPath"';
NUMERICLESSTHAN                : '"NumericLessThan"';
NUMERICLESSTHANPATH            : '"NumericLessThanPath"';
NUMERICLESSTHANEQUALS          : '"NumericLessThanEquals"';
NUMERICLESSTHANEQUALSPATH      : '"NumericLessThanEqualsPath"';
OR                             : '"Or"';
STRINGEQUALS                   : '"StringEquals"';
STRINGEQUALSPATH               : '"StringEqualsPath"';
STRINGGREATERTHAN              : '"StringGreaterThan"';
STRINGGREATERTHANPATH          : '"StringGreaterThanPath"';
STRINGGREATERTHANEQUALS        : '"StringGreaterThanEquals"';
STRINGGREATERTHANEQUALSPATH    : '"StringGreaterThanEqualsPath"';
STRINGLESSTHAN                 : '"StringLessThan"';
STRINGLESSTHANPATH             : '"StringLessThanPath"';
STRINGLESSTHANEQUALS           : '"StringLessThanEquals"';
STRINGLESSTHANEQUALSPATH       : '"StringLessThanEqualsPath"';
STRINGMATCHES                  : '"StringMatches"';
TIMESTAMPEQUALS                : '"TimestampEquals"';
TIMESTAMPEQUALSPATH            : '"TimestampEqualsPath"';
TIMESTAMPGREATERTHAN           : '"TimestampGreaterThan"';
TIMESTAMPGREATERTHANPATH       : '"TimestampGreaterThanPath"';
TIMESTAMPGREATERTHANEQUALS     : '"TimestampGreaterThanEquals"';
TIMESTAMPGREATERTHANEQUALSPATH : '"TimestampGreaterThanEqualsPath"';
TIMESTAMPLESSTHAN              : '"TimestampLessThan"';
TIMESTAMPLESSTHANPATH          : '"TimestampLessThanPath"';
TIMESTAMPLESSTHANEQUALS        : '"TimestampLessThanEquals"';
TIMESTAMPLESSTHANEQUALSPATH    : '"TimestampLessThanEqualsPath"';

SECONDSPATH   : '"SecondsPath"';
SECONDS       : '"Seconds"';
TIMESTAMPPATH : '"TimestampPath"';
TIMESTAMP     : '"Timestamp"';

TIMEOUTSECONDS     : '"TimeoutSeconds"';
TIMEOUTSECONDSPATH : '"TimeoutSecondsPath"';

HEARTBEATSECONDS     : '"HeartbeatSeconds"';
HEARTBEATSECONDSPATH : '"HeartbeatSecondsPath"';

PROCESSORCONFIG : '"ProcessorConfig"';
MODE            : '"Mode"';
INLINE          : '"INLINE"';
DISTRIBUTED     : '"DISTRIBUTED"';
EXECUTIONTYPE   : '"ExecutionType"';
STANDARD        : '"STANDARD"';

ITEMPROCESSOR  : '"ItemProcessor"';
ITERATOR       : '"Iterator"';
ITEMSELECTOR   : '"ItemSelector"';
MAXCONCURRENCY : '"MaxConcurrency"';

RESOURCE       : '"Resource"';
INPUTPATH      : '"InputPath"';
OUTPUTPATH     : '"OutputPath"';
ITEMSPATH      : '"ItemsPath"';
RESULTPATH     : '"ResultPath"';
RESULT         : '"Result"';
PARAMETERS     : '"Parameters"';
RESULTSELECTOR : '"ResultSelector"';

ITEMREADER        : '"ItemReader"';
READERCONFIG      : '"ReaderConfig"';
INPUTTYPE         : '"InputType"';
CSVHEADERLOCATION : '"CSVHeaderLocation"';
CSVHEADERS        : '"CSVHeaders"';
MAXITEMS          : '"MaxItems"';
MAXITEMSPATH      : '"MaxItemsPath"';

NEXT : '"Next"';
END  : '"End"';

CAUSE     : '"Cause"';
CAUSEPATH : '"CausePath"';
ERROR     : '"Error"';
ERRORPATH : '"ErrorPath"';

// Retry.
RETRY           : '"Retry"';
ERROREQUALS     : '"ErrorEquals"';
INTERVALSECONDS : '"IntervalSeconds"';
MAXATTEMPTS     : '"MaxAttempts"';
BACKOFFRATE     : '"BackoffRate"';
MAXDELAYSECONDS : '"MaxDelaySeconds"';
JITTERSTRATEGY  : '"JitterStrategy"';
FULL            : '"FULL"';
NONE            : '"NONE"';

// Catch.
CATCH: '"Catch"';

// ErrorNames
ERRORNAMEStatesALL                             : '"States.ALL"';
ERRORNAMEStatesHeartbeatTimeout                : '"States.HeartbeatTimeout"';
ERRORNAMEStatesTimeout                         : '"States.Timeout"';
ERRORNAMEStatesTaskFailed                      : '"States.TaskFailed"';
ERRORNAMEStatesPermissions                     : '"States.Permissions"';
ERRORNAMEStatesResultPathMatchFailure          : '"States.ResultPathMatchFailure"';
ERRORNAMEStatesParameterPathFailure            : '"States.ParameterPathFailure"';
ERRORNAMEStatesBranchFailed                    : '"States.BranchFailed"';
ERRORNAMEStatesNoChoiceMatched                 : '"States.NoChoiceMatched"';
ERRORNAMEStatesIntrinsicFailure                : '"States.IntrinsicFailure"';
ERRORNAMEStatesExceedToleratedFailureThreshold : '"States.ExceedToleratedFailureThreshold"';
ERRORNAMEStatesItemReaderFailed                : '"States.ItemReaderFailed"';
ERRORNAMEStatesResultWriterFailed              : '"States.ResultWriterFailed"';
// Read-only:
ERRORNAMEStatesRuntime: '"States.Runtime"';

// Strings.
STRINGDOLLAR: '"' (ESC | SAFECODEPOINT)* '.$"';

STRINGPATHCONTEXTOBJ: '"$$' (ESC | SAFECODEPOINT)* '"';

STRINGPATH: '"$' (ESC | SAFECODEPOINT)* '"';

STRING                 : '"' (ESC | SAFECODEPOINT)* '"';
fragment ESC           : '\\' (["\\/bfnrt] | UNICODE);
fragment UNICODE       : 'u' HEX HEX HEX HEX;
fragment HEX           : [0-9a-fA-F];
fragment SAFECODEPOINT : ~ ["\\\u0000-\u001F];

// Numbers.
INT: '0' | [1-9] [0-9]*;

NUMBER: '-'? INT ('.' [0-9]+)? EXP?;

fragment EXP: [Ee] [+\-]? INT;

// Whitespace.
WS: [ \t\n\r]+ -> skip;